package com.ht.api.call.func.impl.wwx;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.sql.DataSource;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.StreamLoadConfig;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.util.HtUtil;
import com.ht.api.open.OpenUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 绑定联系我的客服人员
 * @author asq
 * @createTime 2025年1月13日 22:19:08
 */
@Slf4j
public class WwxContactWayRelAddFunctionCall implements IFunctionCall {
	/** 接口ID：更新企业已配置的「联系我」方式 */
	private static final long API_ID = 1900131140698771456L;
	
	@Override
	public String getName() {
		return "绑定联系我的客服人员";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {
		// 获取登陆用户的数据源
		DataSource ds = me.getDataSource();
		StreamLoadConfig streamLoadConfig = me.getStreamLoadConfig();
		
		// 验证参数
		HtUtil.checkParam(param, "main_id", "user");
		JSONArray userArr = param.getJSONArray("user");
		if (userArr.isEmpty()) {
			throw new HtException("user不能为空~");
		}
		
		// 查询
		String mainId = param.getStr("main_id");
		Entity wxContactWay = Db.createSqlParser("wx_contact_way").findById(ds, mainId);
		if (wxContactWay == null) {
			throw new HtException("数据不存在~");
		}
		
		// 如果有config_id字段，则需要调用企微接口
		boolean needSynWx = StrUtil.isNotBlank(wxContactWay.getStr("config_id"));
		if (needSynWx) {
			// 调用企微接口
			String appId = wxContactWay.getStr("appid");
			JSONObject wxParam = JSONUtil.createObj();
			wxParam.set("config_id", wxContactWay.getStr("config_id"));
			wxParam.set("user", getNewUserArr(wxContactWay, userArr));
			String str = OpenUtil.call(appId, API_ID, wxParam);
			
			// 本地数据库
			JSONObject obj = JSONUtil.parseObj(str);
			if (obj.getInt("errcode") == 0) {
				addRel(streamLoadConfig, wxContactWay, userArr);
				
				HtUtil.createLog(ds, mainId, "绑定联系我的客服人员");
			} else {
				throw new HtException("企微接口返回错误：" + obj.getStr("errmsg"));
			}
		} else {
			addRel(streamLoadConfig, wxContactWay, userArr);
			
			HtUtil.createLog(ds, mainId, "绑定联系我的客服人员");
		}
		
		return JSONUtil.createObj();
	}
	
	/**
	 * 获取需要更新到企业微信中的最新客服userid集合
	 * @param wxContactWay 联系我
	 * @param userArr 本次要绑定的客服userid数组
	 * @return
	 */
	private JSONArray getNewUserArr(Entity wxContactWay, JSONArray userArr) {
		Set<String> set = new HashSet<>();
		
		// 添加本次要绑定的
		for (int i = 0; i < userArr.size(); i++) {
			set.add(userArr.getStr(i));
		}
		
		// 再加上旧的已绑定的
		if (wxContactWay.containsKey("user")) {
			JSONArray oldUserArr = wxContactWay.getJSONArray("user");
			if (oldUserArr != null && !oldUserArr.isEmpty()) {
				for (int i = 0; i < oldUserArr.size(); i++) {
					set.add(oldUserArr.getStr(i));
				}
			}
		}
		
		// 转为JSONArray
		JSONArray arr = JSONUtil.createArray();
		set.stream().forEach(arr::add);
		
		return arr;
	}

	/**
	 * 绑定联系我的客服人员
	 * @param slconfog 数据源
	 * @param wxContactWay 联系我
	 * @param userArr 要绑定的客服userid数组
	 */
	private void addRel(StreamLoadConfig slconfog, Entity wxContactWay, JSONArray userArr) {
		// 最终要保存的数据集合
		List<Entity> dbList = new ArrayList<>();
		
		// 新增联系我客服关联表（排除旧人员已存在的）
		JSONArray oldUserArr = wxContactWay.getJSONArray("user");
		userArr.stream().filter(userid -> {
			if (oldUserArr != null && !oldUserArr.isEmpty()) {
				return oldUserArr.stream().noneMatch(oldUser -> oldUser.equals(userid));
			}
			return true;
		}).forEach(userid -> {
			Entity wxContactWayRelation = Db.createEntity("wx_contact_way_relation");
			wxContactWayRelation.set("contact_way_id", wxContactWay.getMainId());
			wxContactWayRelation.set("userid", userid);
			wxContactWayRelation.set("create_time", DateUtil.now());
			wxContactWayRelation.set("friend_cnt", 0);
			wxContactWayRelation.set("state", wxContactWay.getStr("state"));
			wxContactWayRelation.set("status", 0);
			dbList.add(wxContactWayRelation);
		});
		
		// 联系我主表
		wxContactWay.set("user", getNewUserArr(wxContactWay, userArr));
		dbList.add(wxContactWay);
		
		// 批量写入数据库
		Db.insertBatchWithStream(slconfog, dbList);
	}
}
